package com.ai.imagetext.service;

import com.ai.imagetext.config.AliOSSManager;
import com.ai.imagetext.config.FileUploadConfig;
import com.ai.imagetext.entity.Image;
import com.ai.imagetext.exception.FileUploadException;
import com.ai.imagetext.repository.ImageRepository;
import com.ai.imagetext.util.FileUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import java.awt.*;
import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class FileUploadService {
    
    private final FileUploadConfig fileUploadConfig;
    private final ImageRepository imageRepository;
    private final AIRecognitionService aiRecognitionService;

    @Autowired
    private AliOSSManager aliOSSManager;
    
    @Value("${server.port:8080}")
    private String serverPort;
    
    /**
     * 单文件上传
     */
    @Transactional
    public Image uploadSingleFile(MultipartFile file) {
        log.info("Starting single file upload: {}", file.getOriginalFilename());
        
        // 验证文件
        FileUtils.validateFile(file);

        String originalFilename = file.getOriginalFilename();
        String uniqueFilename = FileUtils.generateUniqueFileName(originalFilename);
        String datePath = generateDatePath();
        String relativePath = datePath + "/" + uniqueFilename;
        String upload ="";

        try {
            upload = aliOSSManager.upload(file, relativePath);
            Dimension dimensions = FileUtils.getImageDimensions(file);
            ServletRequestAttributes attributes = (ServletRequestAttributes)
                    RequestContextHolder.currentRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            Long userId = Long.parseLong(request.getHeader("User"));
            // 创建图片实体
            Image image = new Image();
            image.setUserId(userId);
            image.setName(uniqueFilename);
            image.setOriginalName(originalFilename);
            image.setFilePath(relativePath);
            image.setFileUrl(upload);
            image.setFileSize(file.getSize());
            image.setMimeType(file.getContentType());
            image.setWidth((int) dimensions.getWidth());
            image.setHeight((int) dimensions.getHeight());
            image.setAiRecognitionStatus(Image.AIRecognitionStatus.PENDING);
            image.setUsageCount(0);
            image.setIsDeleted(false);
            // 保存到数据库
            Image savedImage = imageRepository.save(image);
            // 异步执行AI识别
            performAIRecognitionAsync(savedImage,userId);
            log.info("File uploaded successfully: {} -> {}", originalFilename, uniqueFilename);
            return savedImage;
            
        } catch (Exception e) {
            // 如果数据库保存失败，删除已上传的文件
            aliOSSManager.delete(upload);
            throw new FileUploadException("文件上传失败：" + e.getMessage(), e);
        }
    }
    
    /**
     * 异步执行AI识别
     */
    private void performAIRecognitionAsync(Image image,Long userId) {
        // 使用新线程异步执行AI识别
        new Thread(() -> {
            try {
                log.info("Starting AI recognition for image: {}", image.getId());
                aiRecognitionService.recognizeImageTag(image,userId);
            } catch (Exception e) {
                log.error("AI recognition failed for image: {}", image.getId(), e);
            }
        }).start();
    }
    
    /**
     * 批量文件上传
     */
    @Transactional
    public List<Image> uploadMultipleFiles(List<MultipartFile> files) {
        log.info("Starting batch file upload: {} files", files.size());
        
        if (files == null || files.isEmpty()) {
            throw new FileUploadException("没有选择文件");
        }
        
        if (files.size() > 20) {
            throw new FileUploadException("一次最多只能上传20个文件");
        }
        
        List<Image> uploadedImages = new ArrayList<>();
        List<String> uploadedFilePaths = new ArrayList<>();
        
        try {
            for (MultipartFile file : files) {
                if (!file.isEmpty()) {
                    Image image = uploadSingleFile(file);
                    uploadedImages.add(image);
                    uploadedFilePaths.add(fileUploadConfig.getPath() + image.getFilePath());
                }
            }
            
            log.info("Batch upload completed: {} files uploaded successfully", uploadedImages.size());
            return uploadedImages;
            
        } catch (Exception e) {
            // 如果批量上传失败，清理已上传的文件
            log.error("Batch upload failed, cleaning up uploaded files", e);
            for (String filePath : uploadedFilePaths) {
                FileUtils.deleteFile(filePath);
            }
            
            // 删除数据库记录
            if (!uploadedImages.isEmpty()) {
                List<Long> imageIds = uploadedImages.stream().map(Image::getId).toList();
                imageRepository.softDeleteByIds(imageIds);
            }
            
            throw new FileUploadException("批量上传失败：" + e.getMessage(), e);
        }
    }
    
    /**
     * 删除文件
     */
    @Transactional
    public boolean deleteFile(Long imageId) {
        log.info("Deleting file with image ID: {}", imageId);
        try{
            Image referenceById = imageRepository.getReferenceById(imageId);
            String fileUrl = referenceById.getFileUrl();
            // 删除物理文件
            aliOSSManager.delete(fileUrl);
            // 软删除数据库记录
            imageRepository.softDeleteById(imageId);
            log.info("File deletion completed: imageId={}, fileDeleted={}", imageId, true);
            return true;
        }catch (Exception e){
            log.error("error",e);
        }
        return false;
    }
    
    /**
     * 获取文件信息
     */
    public Image getFileInfo(Long imageId) {
        return imageRepository.findByIdAndIsDeletedFalse(imageId)
                .orElseThrow(() -> new IllegalArgumentException("图片不存在或已删除"));
    }
    
    /**
     * 检查文件是否存在
     */
    public boolean fileExists(String filePath) {
        return aliOSSManager.exists(filePath);
    }
    
    /**
     * 获取上传统计信息
     */
    public UploadStatistics getUploadStatistics() {
        long totalImages = imageRepository.countByIsDeletedFalse();
        long totalSize = imageRepository.findByIsDeletedFalse(null).stream()
                .mapToLong(Image::getFileSize)
                .sum();
        
        UploadStatistics stats = new UploadStatistics();
        stats.setTotalImages(totalImages);
        stats.setTotalSize(totalSize);
        stats.setFormattedSize(FileUtils.formatFileSize(totalSize));
        
        return stats;
    }
    
    /**
     * 生成日期路径
     */
    private String generateDatePath() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
    }
    

    
    /**
     * 上传统计信息
     */
    public static class UploadStatistics {
        private long totalImages;
        private long totalSize;
        private String formattedSize;
        
        // Getters and Setters
        public long getTotalImages() { return totalImages; }
        public void setTotalImages(long totalImages) { this.totalImages = totalImages; }
        
        public long getTotalSize() { return totalSize; }
        public void setTotalSize(long totalSize) { this.totalSize = totalSize; }
        
        public String getFormattedSize() { return formattedSize; }
        public void setFormattedSize(String formattedSize) { this.formattedSize = formattedSize; }
    }
}